//
//  HTTPPromise+AFNetworking.m
//  ProductionFrame
//
//  Created by weiyin on 15/10/10.
//  Copyright © 2015年 weiyin. All rights reserved.
//

#import "HTTPPromise+AFNetworking.h"
#import "AFHTTPSessionManager.h"
#import "Constants.h"

@interface AXTAFPromise : HTTPPromise
@end

@implementation AXTAFPromise
- (void)dealloc {
    // nothing
}

@end

static NSMutableArray *sg_requestTasks;

@implementation HTTPPromise (AFNetworking)

+ (AFHTTPSessionManager *)access {
    static AFHTTPSessionManager *access = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURL *baseURL = [NSURL URLWithString:Http_URL];
        access = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
        
        access.responseSerializer.acceptableContentTypes = [access.responseSerializer.acceptableContentTypes setByAddingObjectsFromArray:@[@"application/json",@"text/json",@"text/javascript",@"text/html", @"text/plain"]];
    });
    return access;
}

+ (void)cancelAllRequests {
    @synchronized(self) {
        [[self allTasks] enumerateObjectsUsingBlock:^(HTTPSessionTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task isKindOfClass:[HTTPSessionTask class]]) {
                [task cancel];
            }
        }];
        
        [[self allTasks] removeAllObjects];
    };
}

+ (NSMutableArray *)allTasks {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (sg_requestTasks == nil) {
            sg_requestTasks = [[NSMutableArray alloc] init];
        }
    });
    
    return sg_requestTasks;
}

#pragma mark GET
+ (HTTPPromise *)GET:(NSString *)url
         parameters:(NSDictionary *)parameters{
    return [self GET:url parameters:parameters success:nil failure:nil];
}

+ (HTTPPromise *)GET:(NSString *)url
         parameters:(NSDictionary *)parameters
            success:(HTTPromiseSuccess)success
            failure:(HTTPromiseFailure)failure {
    return [self method:@"GET"
                    url:url
             parameters:parameters
                builder:nil
                success:success
                failure:failure];
}

#pragma mark POST object
+ (HTTPPromise *)POST:(NSString *)url
          parameters:(NSDictionary *)parameters
                json:(NSData *)json{
    return [self POST:url parameters:parameters json:json success:nil failure:nil];
}

+ (HTTPPromise *)POST:(NSString *)url
          parameters:(NSDictionary *)parameters
                json:(NSData *)json
             success:(HTTPromiseSuccess)success
             failure:(HTTPromiseFailure)failure {
    //增加必传参数:常德医院
    id data = [self toNSDictionary:json];
    NSDictionary *dataDict = data;
    NSMutableDictionary *mutableData;
    if (dataDict == nil && dataDict.count == 0) {
        mutableData = [[NSMutableDictionary alloc] init];
    }else
    {
        mutableData = [[NSMutableDictionary alloc] initWithDictionary:dataDict];
    }
    
//    [mutableData setObject:@"hn-cd-07310001" forKey:@"regionCode"];
//    [mutableData setObject:@"07310001" forKey:@"instanceCode"];
    
    NSData *newjsonData;
    
    if ([NSJSONSerialization isValidJSONObject:mutableData])
    {
        NSError *error;
        newjsonData = [NSJSONSerialization dataWithJSONObject:mutableData options:NSJSONWritingPrettyPrinted error:&error];
        NSString *json =[[NSString alloc] initWithData:newjsonData encoding:NSUTF8StringEncoding];
        NSLog(@"json data:%@",json);
    }
    
//    HTTPPromise *Promise = [self method:@"POST"
//                                    url:url
//                             parameters:parameters
//                                builder:newjsonData ? ^(NSMutableURLRequest *request) {
//                                    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
//                                    [request setHTTPBody:newjsonData];
//                                } : nil
//                                success:success
//                                failure:failure];
//    id responseObj = Promise.then(^{});
//    NSLog(@"%@",responseObj);
    
    
    return  [self method:@"POST"
                     url:url
              parameters:parameters
                 builder:newjsonData ? ^(NSMutableURLRequest *request) {
                     [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
                     [request setHTTPBody:newjsonData];
                 } : nil
                 success:success
                 failure:failure];;
}

#pragma mark POST string
+ (HTTPPromise *)POST:(NSString *)url
          parameters:(NSDictionary *)parameters
                body:(NSString *)body
             success:(HTTPromiseSuccess)success
             failure:(HTTPromiseFailure)failure {
    return [self method:@"POST"
                    url:url
             parameters:parameters
                builder:body ? ^(NSMutableURLRequest *request) {
                    [request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
                } : nil
                success:success
                failure:failure];
}

#pragma mark ------------
+ (HTTPPromise *)method:(NSString *)method
                   url:(NSString *)url
            parameters:(NSDictionary *)parameters
               builder:(void (^)(NSMutableURLRequest *request))builder
               success:(HTTPromiseSuccess)success
               failure:(HTTPromiseFailure)failure {
    
    
    // create request
    AFHTTPSessionManager *access = [self access];
    NSString *URLString;
    
    if (access.baseURL != nil) {
        URLString = [[NSURL URLWithString:url relativeToURL:access.baseURL] absoluteString];
    }
    
    if (URLString != nil) {
        NSMutableURLRequest *request = [access.requestSerializer requestWithMethod:method
                                                                         URLString:URLString
                                                                        parameters:parameters
                                                                             error:NULL];
        
        if(!HTCFStringIsNull(encryptionToken))
        {
            [request setValue:encryptionToken forHTTPHeaderField:@"userSign"];
        }
//        [request setValue:@"0" forHTTPHeaderField:@"t_type"];
//        [request setValue:REGION_CODE forHTTPHeaderField:@"regionCode"];
        if (builder) builder(request);
        
        // send HTTPPromise
        return [HTTPPromise promiseWithRequest:request]
        .then(^(id responseObject) {
            if (success) success(responseObject);
        })
        .catch(^(NSError *error) {
            if (failure) failure(error);
            return (HTTPPromise *)nil;
        });
    }
    
    return nil;
}

+ (HTTPPromise *)promiseWithRequest:(NSURLRequest *)request{
    AXTAFPromise *promise = [AXTAFPromise new:^(HTTPPromiseFulfiller fulfiller, HTTPPromiseRejecter rejecter) {
        AFHTTPSessionManager *access = [self access];
        
        __weak __typeof(self)weakSelf = self; 
        NSURLSessionDataTask *task = [access dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            __strong __typeof(weakSelf)strongSelf = weakSelf;
            NSInteger statusCode = [strongSelf showResponseCode:response];
            if (statusCode == 200) {
                [strongSelf judgementErrorCode:responseObject];
                fulfiller(responseObject);
            }else
            {
                rejecter(error);
            }
        }];
        //使用resume方法启动任务
        [task resume];
    }];
    return promise;
}

+ (void)saveCookies{
    
    NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
    [defaults setObject: cookiesData forKey: @"sessionCookies"];
    [defaults synchronize];
}

+ (void)loadCookies{
    
    NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData: [[NSUserDefaults standardUserDefaults] objectForKey: @"sessionCookies"]];
    
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    for (NSHTTPCookie *cookie in cookies){
        [cookieStorage setCookie: cookie];
    }
}

// 将JSON串转化为id
+ (id)toNSDictionary:(NSData *)jsonData{
    NSError *error = nil;
    if(jsonData != nil)
    {
        id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingAllowFragments
                                                          error:&error];
        
        if (jsonObject != nil && error == nil){
            return jsonObject;
        }else{
            // 解析错误
            return nil;
        }
    }
    return nil;
}

/* 输出http响应的状态码 */
+ (NSInteger)showResponseCode:(NSURLResponse *)response {
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
    NSInteger responseStatusCode = [httpResponse statusCode];
    NSLog(@"%ld", (long)responseStatusCode);
    
    //获取返回的header
    NSDictionary *allHeaders = httpResponse.allHeaderFields;
    if(!HTCFStringIsNull(allHeaders[@"accessToken"])){
        HTCFUDFCache(kAccessTokenKey,allHeaders[@"accessToken"]);
        accessToken = HTCFUDFGetValue(kAccessTokenKey);
        if (!HTCFUDFEmptyValue(kRefreshTokenKey)) {
            refreshToken = HTCFUDFGetValue(kRefreshTokenKey);
        }
        
        if (!HTCFUDFEmptyValue(kUserIdKey)) {
            userId = [HTCFUDFGetValue(kUserIdKey) intValue];
        }
        
        int newuserId = (int)userId;
        NSString *newrefreshToken = refreshToken;
        
        NSLog(@"newuserId----------%d",newuserId);
        NSLog(@"newrefreshToken----------%@",newrefreshToken);
        if(newuserId > 0 && !HTCFStringIsNull(newrefreshToken)){
            NSString *encryptionStr = [NSString stringWithFormat:@"%@|%d|%@|%@",accessToken,newuserId,refreshToken,IDFV];
            
            NSString *privateKey = HTCFAES128EncryptUtil(encryptionStr,signKey);
            
            HTCFUDFCache(kSignServiceKey,privateKey);
            encryptionToken = privateKey;
        }
    }
    
    return responseStatusCode;
}

+ (void)judgementErrorCode:(id _Nullable)responseObject
{
    if ([responseObject[@"ret"] intValue] >=100 && [responseObject[@"ret"] intValue] <= 199) {
        HTCFNotificationPost(RequestErrorCodeNotification);
    }
}

@end
